﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace DesktopLauncher
{
    public partial class InputDialog : Form
    {
        bool discardChanges = true;
        Image defaultImage;
        OpenFileDialog fileDialog;
        string ImagePath;
        public InputDialog()
        {
            InitializeComponent();

            defaultImage = new Bitmap(this.iconPictureBox.BackgroundImage);

            fileDialog = new OpenFileDialog();
            fileDialog.Title = "Choose file";
            fileDialog.Filter = "Executable file|*.exe";
            fileDialog.Multiselect = false;
        }

        /// <summary>
        /// Will show input dialog (overloading base ShowDialog) with MenuItemExtended component - so it can simply change values
        /// </summary>
        /// <param name="menuItem"></param>
        /// <returns></returns>
        public DialogResult ShowDialog(ref MenuItemExtended menuItem)
        {
            if (menuItem.Parrent != null)
            {
                this.itemPositionUpDown.Maximum = menuItem.Parrent.DropDownItems.Count - 1;
                this.itemPositionUpDown.Value = menuItem.Parrent.DropDownItems.IndexOf(menuItem);
            }
            this.InputTextBox.Text = menuItem.Text;
            this.iconPictureBox.Image = menuItem.Image;
            ImagePath = menuItem.ImagePath;
            if (menuItem.Image != null) this.iconPictureBox.BackgroundImage = null;
            this.runPathTextBox.Text = menuItem.RunPath;

            DialogResult result = base.ShowDialog();
            if (discardChanges) return System.Windows.Forms.DialogResult.Abort;

            menuItem.Text = this.InputTextBox.Text;
            menuItem.Image = this.iconPictureBox.Image;
            menuItem.ImagePath = ImagePath;
            menuItem.RunPath = this.runPathTextBox.Text;
            if (menuItem.Parrent != null)
            {
                menuItem.Parrent.DropDownItems.Remove(menuItem);
                menuItem.Parrent.DropDownItems.Insert((int)this.itemPositionUpDown.Value, menuItem);
            }
            return result;
        }

        // special dialog for picking icons (also can get icon from *.exe files)
        [DllImport("shell32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
        private static extern int PickIconDlg(IntPtr hwndOwner, System.Text.StringBuilder lpstrFile, int nMaxFile, ref int lpdwIconIndex);

        private void iconPictureBox_Click(object sender, EventArgs e)
        {
            string iconfile;
            int iconindex = 0;
            int retval;
            System.Text.StringBuilder sb;

            iconfile = Environment.GetFolderPath(Environment.SpecialFolder.System);
            iconfile = iconfile + @"\shell32.dll";
            sb = new System.Text.StringBuilder(iconfile, 500);
            retval = PickIconDlg(this.Handle, sb, sb.Capacity, ref iconindex);
            iconfile = sb.ToString();

            if (retval == 1)
            {
                ImagePath = iconfile + "," + iconindex;
                iconPictureBox.Image = extractIcon(iconfile, iconindex).ToBitmap();
                this.iconPictureBox.BackgroundImage = null;
            }
            else
            {
                ImagePath = null;
                this.iconPictureBox.Image = null;
                this.iconPictureBox.BackgroundImage = defaultImage;
            }
        }

        // get icon also can extract icon from *.exe file
        [DllImport("shell32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
        public static extern IntPtr ExtractIcon(IntPtr hInstance, string strFileName, uint uiIconIndex);

        private static Icon extractIcon(string strPath, int nIndex)
        {
            Icon icon = null;
            IntPtr hIcon = ExtractIcon(IntPtr.Zero, strPath, (uint)nIndex);
            if (IntPtr.Zero != hIcon)
            {
                icon = Icon.FromHandle(hIcon);
            }
            return icon;
        }

        public static Image GetImageFromPath(string path)
        {
            if (String.IsNullOrEmpty(path)) return null;
            if (!path.Contains(','))
            {
                if (!File.Exists(path)) return null;
                return Image.FromFile(path);
            }

            int nIndex = int.Parse(path.Split(',').Last().Trim());
            string imgPath = path.Substring(0, path.LastIndexOf(','));
            if (!File.Exists(imgPath)) return null;
            return extractIcon(imgPath, nIndex).ToBitmap();
        }

        private void openFileDialogButton_Click(object sender, EventArgs e)
        {
            if (this.runPathTextBox.Text.Length > 0)
                fileDialog.InitialDirectory = this.runPathTextBox.Text;

            if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.runPathTextBox.Text = fileDialog.FileName;
                // try get icon from file
                Image img = GetImageFromPath(fileDialog.FileName + ", 0");
                if ((img != null) && (iconPictureBox.Image == null))
                {
                    ImagePath = fileDialog.FileName + ", 0";
                    this.iconPictureBox.Image = img;
                    this.iconPictureBox.BackgroundImage = null;
                }
            }
        }

        private void closeButton_Click(object sender, EventArgs e)
        {
            discardChanges = false;
            this.Close();
        }

        private void discardButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
